package com.ourway.controller;


import cn.hutool.core.date.DateTime;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.liuweiheng.base.constant.redis.GlobalStrRedisConstant;
import com.liuweiheng.base.entity.R;
import com.liuweiheng.base.utils.GlobalStrRedisUtil;
import com.ourway.constant.FeiShuConstants;
import com.ourway.entity.vo.FeiShuApprovalInfoResponseVo;
import com.ourway.entity.vo.FeiShuEventSubscribeInfoVo;
import com.ourway.entity.vo.FeiShuMessageCardCallBackVo;
import com.ourway.service.IFeiShuService;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.*;

import java.io.Serializable;

/**
 * 事件控制器
 *
 * @author lwh
 * @date 2021/12/03
 */
@Slf4j
@RestController
@RequestMapping("/feishu/event")
public class FeiShuEventController implements Serializable {

    private final IFeiShuService feiShuService;

    private final FeiShuConstants feiShuConstants;

    public FeiShuEventController(IFeiShuService feiShuService, FeiShuConstants feiShuConstants) {
        this.feiShuService = feiShuService;
        this.feiShuConstants = feiShuConstants;
    }

    /**
     * 响应FeiShu事件订阅
     * @param param 事件订阅信息
     * @return challenge
     * @throws JSONException json异常
     */
    @PostMapping("/eventSubScribe")
    public String eventSubScribeResponse(@RequestBody FeiShuEventSubscribeInfoVo param) throws JSONException {
        log.info(param.toString());

        JSONObject result = new JSONObject();
        result.put("challenge", param.getChallenge());

        if (StrUtil.isBlank(param.getUuid()) && null == param.getHeader()) {
            return result.toString();
        }

        // 校验消息是否已经成功消费
        String eventId = null == param.getSchema() ? param.getUuid() : param.getHeader().getEvent_id();

        if (GlobalStrRedisUtil.containHashKey(GlobalStrRedisConstant.FEISHU_SUBSCRIBE_EVENT_ID, eventId)) {
            return result.toString();
        }

        // 订阅事件：机器人接受消息
        if (null != param.getSchema() && param.getHeader().getEvent_type().equals(FeiShuConstants.EVENT_SUBSCRIBE_TYPE_ROBOT_RECEIVE_MESSAGE)) {
            ThreadUtil.execute(() -> {
                String content = JSONUtil.toBean(param.getEvent().getMessage().getContent(), String.class);
                // 发送
                String answer = "对不起，我无法回答您的问题";
                String accessToken = feiShuService.getTenantAccessToken();
                String messageId = param.getEvent().getMessage().getMessage_id();
                try {
                    feiShuService.replyMsg(accessToken, messageId, answer, param.getHeader().getEvent_id());
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            });
        }

        // 订阅事件：请假审批创建
        if (null == param.getSchema() && feiShuConstants.getLeaveApprovalCode().equals(param.getEvent().getApproval_code()) && "PENDING".equals(param.getEvent().getStatus())) {
            ThreadUtil.execute(() -> {
                // 获取当前实例信息
                String instanceCode = param.getEvent().getInstance_code();
                String accessToken = feiShuService.getTenantAccessToken();
                FeiShuApprovalInfoResponseVo approvalInfo = feiShuService.getApprovalInfo(accessToken, instanceCode);

                log.info(approvalInfo.toString());

                // 编辑业务卡片
                String approvalUserId = approvalInfo.getData().getTask_list().get(0).getOpen_id();
                String replyUserId = approvalInfo.getData().getOpen_id();
                String startTime = approvalInfo.getData().getTask_list().get(0).getStart_time();
                String endTime = approvalInfo.getData().getTask_list().get(0).getEnd_time();
                String approvalName = approvalInfo.getData().getApproval_name();

                startTime = new DateTime(Long.parseLong(startTime)).toString("YYYY-MM-dd HH:mm:ss");
                endTime = new DateTime(Long.parseLong(endTime)).toString("YYYY-MM-dd HH:mm:ss");

                feiShuService.sendLeaveApprovalCard(accessToken, replyUserId, approvalUserId, startTime, endTime, approvalName, instanceCode, eventId);

            });
        }

        return result.toString();
    }

    /**
     * 消息卡片交互回调
     * @param param 回调参数
     * @return challenge
     * @throws JSONException json转换异常
     */
    @PostMapping("/messageCardCallBack")
    public String messageCardCallBack(@RequestBody FeiShuMessageCardCallBackVo param) throws JSONException {
        JSONObject result = new JSONObject();
        result.put("challenge", param.getChallenge());

        log.info(param.toString());

        if (null == param.getAction()) {
            return result.toString();
        }

        // 处理审批通过事件
        final String approveEventLeave = "approve";

        if (approveEventLeave.equals(param.getAction().getValue().getChosen())) {
            ThreadUtil.execute(() -> {
                String accessToken = feiShuService.getTenantAccessToken();
                String instanceCode = param.getAction().getValue().getInstanceCode();
                FeiShuApprovalInfoResponseVo approvalInfo = feiShuService.getApprovalInfo(accessToken, instanceCode);
                // 同意审批任务
                String approvalCode = approvalInfo.getData().getApproval_code();
                String openId = approvalInfo.getData().getOpen_id();
                String userId = approvalInfo.getData().getUser_id();
                String taskId = approvalInfo.getData().getTask_list().get(0).getId();

                String comment = "ok";
                feiShuService.approveInstance(accessToken, approvalCode, instanceCode, openId, userId, taskId, comment);
                // 更新卡片信息
                String messageId = param.getOpen_message_id();
                String approvalName = approvalInfo.getData().getApproval_name();
                feiShuService.updateLeaveApprovalCard(openId, approvalName, messageId);
            });
        }

        return result.toString();
    }

    /**
     * 订阅审批事件(每个应用只需执行一次即可)
     */
    @GetMapping("/subScribeApproval")
    public R subScribeApproval() {
        // 获取 tenant_access_token
        String tenantAccessToken = feiShuService.getTenantAccessToken();
        feiShuService.subScribeApproval(tenantAccessToken);
        return R.ok();
    }

}
